﻿using System;
using System.Linq;

namespace AutoMapper
{
	public static class MappingExtensions
	{
		public static object Map(this object @this, Type destinationType)
		{
			return Mapper.Map(@this, @this.GetType(), destinationType);
		}

		public static TDestination Map<TDestination>(this object @this)
		{
			if (@this == null)
			{
				return default(TDestination);
			}

			return (TDestination)@this.Map(typeof(TDestination));
		}

		/// <summary>
		/// Maps source to new destination.
		/// </summary>
		/// <typeparam name="TSource">The type of the source.</typeparam>
		/// <typeparam name="TDestination">The type of the destination.</typeparam>
		/// <param name="this">The this.</param>
		/// <returns></returns>
		public static TDestination MapNew<TSource, TDestination>(this TSource @this)
		{
			return Mapper.Map<TSource, TDestination>(@this);
		}

		/// <summary>
		/// Maps source to update destination.
		/// </summary>
		/// <typeparam name="TSource">The type of the source.</typeparam>
		/// <typeparam name="TDestination">The type of the destination.</typeparam>
		/// <param name="this">The this.</param>
		/// <param name="destination">The destination.</param>
		/// <returns></returns>
		public static void MapUpdate<TSource, TDestination>(this TSource @this, TDestination destination)
		{
			Mapper.DynamicMap<TSource, TDestination>(@this, destination);
		}

		public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
		{
			var sourceType = typeof(TSource);
			var destinationType = typeof(TDestination);
			var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType) && x.DestinationType.Equals(destinationType));
			foreach (var property in existingMaps.GetUnmappedPropertyNames())
			{
				expression.ForMember(property, opt => opt.Ignore());
			}
			return expression;
		}
	}
}
